package com.yunchang.springboot.scheduled.mwsfinance;

import com.yunchang.springboot.base.BaseService;
import com.yunchang.springboot.mapper.mwsfinance.FFbaShipmentSalesMapper;
import com.yunchang.springboot.mapper.mwsfinance.FInventoryDailyMapper;
import com.yunchang.springboot.mapper.mwsfinance.FReimbursementMapper;
import com.yunchang.springboot.mapper.mwsreport.MwsReimbursementsMapper;
import com.yunchang.springboot.mapper.mwsutils.CwfzCurrencyCountryMapper;
import com.yunchang.springboot.mapper.mwsutils.CwfzFinancialSubjectsMapper;
import com.yunchang.springboot.models.mwsfinance.FReimbursement;
import com.yunchang.springboot.models.mwsfinance.FReimbursementQuantity;
import com.yunchang.springboot.models.mwsreportbean.MwsReimbursements;
import com.yunchang.springboot.utils.DateUtil;
import com.yunchang.springboot.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

/**
 * 赔偿
 */
@Component
@Configuration
@Service
@Slf4j
@EnableScheduling
public class FReimbursementsScheduled extends BaseService {

    static final String REIMBURSEMENT_REVERSAL = "Reimbursement_Reversal";

    static final String OTHER = "其他";

    static Integer LIMIT_VALUE = 10000;

    static final List<String> EU_COUNTRY_LIST = Arrays.asList("DE", "FR", "IT", "UK", "ES");

    static String DOCUMENTS_ID = "PCD";

    static String DOCUMENTS_ID_PUSH = "PCCKD";

    /**
     * 出入库明细
     */
    @Autowired
    FInventoryDetailsScheduled fInventoryDetailsScheduled;

    /**
     * 赔偿原始数据
     */
    private MwsReimbursementsMapper mwsReimbursementsMapper;

    @Autowired
    public void setMwsReimbursementsMapper(MwsReimbursementsMapper mwsReimbursementsMapper) {
        this.mwsReimbursementsMapper = mwsReimbursementsMapper;
    }

    /**
     * 获取country
     */
    private CwfzCurrencyCountryMapper cwfzCurrencyCountryMapper;

    @Autowired
    public void setCwfzCurrencyCountryMapper(CwfzCurrencyCountryMapper cwfzCurrencyCountryMapper) {
        this.cwfzCurrencyCountryMapper = cwfzCurrencyCountryMapper;
    }

    /**
     * 赔偿财务数据
     */
    private FReimbursementMapper fReimbursementMapper;

    @Autowired
    public void setFReimbursementMapper(FReimbursementMapper fReimbursementMapper) {
        this.fReimbursementMapper = fReimbursementMapper;
    }

    /**
     * 获取科目
     */
    private CwfzFinancialSubjectsMapper cwfzFinancialSubjectsMapper;

    @Autowired
    public void setCwfzFinancialSubjectsMapper(CwfzFinancialSubjectsMapper cwfzFinancialSubjectsMapper) {
        this.cwfzFinancialSubjectsMapper = cwfzFinancialSubjectsMapper;
    }

    /**
     * 库存数据
     */
    private FInventoryDailyMapper fInventoryDailyMapper;

    @Autowired
    public void setFInventoryDailyMapper(FInventoryDailyMapper fInventoryDailyMapper) {
        this.fInventoryDailyMapper = fInventoryDailyMapper;
    }

    /**
     * 获取costUnit
     */
    private FFbaShipmentSalesMapper fFbaShipmentSalesMapper;

    @Autowired
    public void setFFbaShipmentSalesMapper(FFbaShipmentSalesMapper fFbaShipmentSalesMapper) {
        this.fFbaShipmentSalesMapper = fFbaShipmentSalesMapper;
    }


    public void getFReimbursements(String date) {
        List<MwsReimbursements> mwsReimbursementsList = mwsReimbursementsMapper.selectByFinanceStatus(1, null, date);
        Integer mwsReimbursementsListSize = mwsReimbursementsList.size();
        int forNum = 1;
        log.info("赔偿原始数据的数量为：" + mwsReimbursementsListSize);
        if (mwsReimbursementsListSize > LIMIT_VALUE) {
            forNum += mwsReimbursementsListSize / LIMIT_VALUE;
            for (; forNum > 0; forNum--) {
                log.info("赔偿生成财务数据生成次数：" + forNum);
                mwsReimbursementsList = mwsReimbursementsMapper.selectByFinanceStatus(1, LIMIT_VALUE, date);
                mwsReimbursementsDispose(mwsReimbursementsList);
            }
        } else {
            mwsReimbursementsDispose(mwsReimbursementsList);
        }
        getFReimbursementQuantity();
    }

    public void mwsReimbursementsDispose(List<MwsReimbursements> mwsReimbursementsList) {
        if (null != mwsReimbursementsList && !mwsReimbursementsList.isEmpty()) {
            List<Object> fReimbursementInsertList = new ArrayList<>();
            for (MwsReimbursements mwsReimbursements : mwsReimbursementsList) {
                FReimbursement fReimbursement = new FReimbursement();
                fReimbursement.setIsAdjustManauly(1);
                fReimbursement.setApprovalStatus(1);
                fReimbursement.setIsPushStatus(1);
                fReimbursement.setDocumentsId(DOCUMENTS_ID + UUIDUtil.getUUID());
                String sellerId = mwsReimbursements.getSellerId();
                fReimbursement.setSellerId(sellerId);
                String currencyUnit = mwsReimbursements.getCurrencyUnit();
                if (StringUtils.isEmpty(getCountryByCurrencyUnit(currencyUnit))) {
                    fReimbursement.setIsAdjustManauly(2);
                }
                String country = getCountryByCurrencyUnit(currencyUnit);
                if (EU_COUNTRY_LIST.contains(country)) {
                    country = "EU";
                }
                fReimbursement.setCountry(country);
                String approvalDate = mwsReimbursements.getApprovalDate();
                fReimbursement.setApprovalDate(approvalDate);
                fReimbursement.setReimbursementId(mwsReimbursements.getReimbursementId());
                String amazonOrderId = mwsReimbursements.getAmazonOrderId();
                fReimbursement.setAmazonOrderId(amazonOrderId);
                String reason = mwsReimbursements.getReason();
                fReimbursement.setReason(reason);
                String originalReimbursementId = mwsReimbursements.getOriginalReimbursementId();
                fReimbursement.setOriginalReimbursementId(originalReimbursementId);
                String originalReimbursementType = mwsReimbursements.getOriginalReimbursementType();
                fReimbursement.setOriginalReimbursementType(originalReimbursementType);
                String originalAmazonOrderId = getOriginalAmazonOrderId(sellerId, reason, originalReimbursementId, originalReimbursementType);
                fReimbursement.setOriginalAmazonOrderId(originalAmazonOrderId);
                String sku = mwsReimbursements.getSku();
                fReimbursement.setSku(sku);
                fReimbursement.setFnsku(mwsReimbursements.getFnsku());
                Integer quantityReimbursedInventory = mwsReimbursements.getQuantityReimbursedInventory();
                if (null == quantityReimbursedInventory) {
                    quantityReimbursedInventory = 0;
                }
                fReimbursement.setQuantityReimbursedInventory(quantityReimbursedInventory);
                Integer quantity = mwsReimbursements.getQuantityReimbursedCash();
                fReimbursement.setQuantity(quantity);
                String type = getType(reason, originalReimbursementType, sellerId, amazonOrderId, sku, quantity, quantityReimbursedInventory, originalReimbursementId, approvalDate,originalAmazonOrderId);
                if (type.equals(OTHER)) {
                    fReimbursement.setIsAdjustManauly(2);
                    fReimbursement.setType(OTHER);
                } else {
                    fReimbursement.setType(type);
                }
                Double priceUnit = Math.abs(mwsReimbursements.getAmountPerUnit());
                fReimbursement.setPriceUnit(priceUnit);
                fReimbursement.setAmount(new BigDecimal(quantity * priceUnit).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                fReimbursement.setCurrency(currencyUnit);
                fReimbursement.setDebitSubjectId(getDebitSubjectIdFromReimbursement(type));
                fReimbursement.setCreditSubjectId(getCreditSubjectIdFromReimbursement(type));
                fReimbursement.setCreateTime(DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
                fReimbursement.setUpdateTime(DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
                fReimbursementInsertList.add(fReimbursement);
                mwsReimbursements.setFinanceStatus(2);
            }
            try {
                baseInsertList(fReimbursementInsertList);
                mwsReimbursementsMapper.updateFinanceStatusByMwsReimbursementsList(mwsReimbursementsList);
                log.info("赔偿财务数据已生成");
            } catch (Exception e) {
                log.error("插入数据时出现错误，赔偿" + e);
                throw new RuntimeException("插入数据时出现错误，赔偿");
            }
        } else {
            log.info("未查询到对应的赔偿数据列表，时间为" + DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
        }
    }


    /**
     * 获取赔偿下推数据
     */
    public void getFReimbursementQuantity() {
        List<String> typeList = Arrays.asList("未退货赔偿", "退货损坏赔偿");
        String reason = "Reimbursement_Reversal";
        List<FReimbursement> fReimbursementList = fReimbursementMapper.selectByTypeListAndIsPushStatusAndNotReason(typeList, 1, reason);
        if (null != fReimbursementList && !fReimbursementList.isEmpty()) {
            List<Object> fReimbursementQuantityInsertList = new ArrayList<>();
            for (FReimbursement fReimbursement : fReimbursementList) {
                FReimbursementQuantity fReimbursementQuantity = new FReimbursementQuantity();
                fReimbursementQuantity.setStatus(1);
                fReimbursementQuantity.setIsInventoryDetails(1);
                fReimbursementQuantity.setDocumentsId(DOCUMENTS_ID_PUSH + UUIDUtil.getUUID());
                String sellerId = fReimbursement.getSellerId();
                fReimbursementQuantity.setSellerId(sellerId);
                String country = fReimbursement.getCountry();
                fReimbursementQuantity.setCountry(country);
                fReimbursementQuantity.setDate(fReimbursement.getApprovalDate());
                fReimbursementQuantity.setReimbursementId(fReimbursement.getReimbursementId());
                String amazonOrderId = fReimbursement.getAmazonOrderId();
                fReimbursementQuantity.setAmazonOrderId(amazonOrderId);
                String sku = fReimbursement.getSku();
                fReimbursementQuantity.setSku(sku);
                String fnSku = fReimbursement.getFnsku();
                fReimbursementQuantity.setFnsku(fnSku);
                String type = fReimbursement.getType();
                fReimbursementQuantity.setType(type);
                Integer quantity = Math.abs(fReimbursement.getQuantity());
                fReimbursementQuantity.setQuantity(quantity);
                Double costUnit;
                Map<String, Double> costUnitMap = getCostUnit(sellerId, country, sku, amazonOrderId);
                if (null != costUnitMap && !costUnitMap.isEmpty()) {
                    if (costUnitMap.containsKey("costUnit2")) {
                        fReimbursementQuantity.setStatus(2);
                        costUnit = costUnitMap.get("costUnit2");
                        fReimbursementQuantity.setCostUnit(costUnitMap.get("costUnit2"));
                    } else {
                        costUnit = costUnitMap.get("costUnit1");
                        fReimbursementQuantity.setCostUnit(costUnitMap.get("costUnit1"));
                    }
                    fReimbursementQuantity.setAmount(quantity * costUnit);
                }
                fReimbursementQuantity.setCurrency("RMB");
                fReimbursementQuantity.setDebitSubjectId(getDebitSubjectIdFromReimbursementPush(type));
                fReimbursementQuantity.setCreditSubjectId(getCreditSubjectIdFromReimbursementPush(type));
                fReimbursementQuantity.setCreateTime(DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
                fReimbursementQuantity.setUpdateTime(DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
                fReimbursementQuantityInsertList.add(fReimbursementQuantity);
                fReimbursement.setIsPushStatus(2);
            }
            try {
                baseInsertList(fReimbursementQuantityInsertList);
                fReimbursementMapper.updateIsPushStatusByFReimbursementList(fReimbursementList);
                log.info("赔偿下推财务数据已生成");
            } catch (Exception e) {
                log.error("插入数据时出现错误，赔偿下推数据" + e);
                throw new RuntimeException("插入数据时出现错误，赔偿下推数据");
            }
        } else {
            log.info("未查询到对应的赔偿下推的财务数据列表，时间为" + DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
        }
    }

    /**
     * 根据currencyUnit 获取country
     *
     * @param currencyUnit
     * @return
     */
    public String getCountryByCurrencyUnit(String currencyUnit) {
        if (StringUtils.isEmpty(currencyUnit)) {
            log.info("根据currencyUnit 获取country,currencyUnit为空，获取赔偿财务数据！");
            return "";
        }
        return cwfzCurrencyCountryMapper.getCountryByCurrency(currencyUnit);
    }

    /**
     * 根据approvalDate 获取warehouseDate
     *
     * @param approvalDate
     * @return
     */
    public String getWarehouseDate(String approvalDate) throws ParseException {
        if (StringUtils.isEmpty(approvalDate)) {
            return "";
        }
        String warehouseDate;
        String standardReturnDate = approvalDate.substring(0, 10) + " 08:00:00";
        if (1 == DateUtil.compateTime(approvalDate, standardReturnDate) || 0 == DateUtil.compateTime(approvalDate, standardReturnDate)) {
            warehouseDate = approvalDate.substring(0, 10);
        } else {
            warehouseDate = DateUtil.dateToFutureDate(approvalDate.substring(0, 10), -1);
        }
        return warehouseDate;
    }

    /**
     * 根据reason 和  originalReimbursementType 进行第一步判断，然后使用sellerId 和 originalReimbursementId 获取对应的amazonOrderId
     *
     * @param sellerId
     * @param reason
     * @param originalReimbursementId
     * @param originalReimbursementType
     * @return
     */
    public String getOriginalAmazonOrderId(String sellerId, String reason, String originalReimbursementId, String originalReimbursementType) {
        List<String> originalReimbursementTypes = Arrays.asList("CustomerReturn", "CustomerServiceIssue");
        if (StringUtils.isEmpty(sellerId) || StringUtils.isEmpty(reason) || StringUtils.isEmpty(originalReimbursementId) || StringUtils.isEmpty(originalReimbursementType)) {
            return "";
        }
        if (reason.equals(REIMBURSEMENT_REVERSAL) && originalReimbursementTypes.contains(originalReimbursementType)) {
            return mwsReimbursementsMapper.selectAmazonOrderIdBySellerIdAndOriginalReimbursementId(sellerId, originalReimbursementId);
        }
        return "";
    }

    /**
     * 获取type
     *
     * @param reason
     * @param originalReimbursementType
     * @return
     */
    public String getType(String reason, String originalReimbursementType, String sellerId, String orderId, String sku, Integer quantity, Integer quantityReimbursedInventory, String originalReimbursementId, String approvalDate,String originalAmazonOrderId) {
        if (!StringUtils.isEmpty(approvalDate)) {
            approvalDate = approvalDate.substring(0, 10);
        }
        if (reason.equals(REIMBURSEMENT_REVERSAL)) {
            switch (originalReimbursementType) {
                case "Damaged_Warehouse":
                    return "在仓损坏赔偿";
                case "Lost_Warehouse":
                    return "在仓丢失赔偿";
                case "Lost_Inbound":
                    return "入库丢失赔偿";
                case "FeeCorrection":
                    return "FBA物流费调整";
                case "CustomerServiceIssue":
                    return "客户服务问题";
                case "CustomerReturn":
                    String type = fReimbursementMapper.selectTypeBySellerIdAndOriginalReimbursementIdAndSku(sellerId, originalReimbursementId, sku);
                    if (!StringUtils.isEmpty(type)) {
                        return type;
                    }
                    Integer sumQuantity = fInventoryDailyMapper.selectSumQuantityBySellerIdAndRelatedIdAndSkuAndWarehouse(sellerId, originalAmazonOrderId, sku, "140601", approvalDate);
                    if (null == sumQuantity) {
                        sumQuantity = 0;
                    }
                    if (sumQuantity != 0) {
                        if (sumQuantity >= quantityReimbursedInventory) {
                            return "退货损坏赔偿";
                        }
                    }
                    Integer sumQuantity2 = fInventoryDailyMapper.selectSumQuantityBySellerIdAndRelatedIdAndSkuAndWarehouse(sellerId, originalAmazonOrderId, sku, "140201", approvalDate);
                    if (null != sumQuantity2) {
                        if (sumQuantity2 > 0) {
                            return "未退货赔偿";
                        }
                        if (sumQuantity2 < 0) {
                            return "额外赔偿";
                        }
                    }
                    break;
                default:
                    return "其他";
            }
        } else {
            switch (reason) {
                case "Damaged_Warehouse":
                    return "在仓损坏赔偿";
                case "Lost_Warehouse":
                    return "在仓丢失赔偿";
                case "Lost_Inbound":
                    return "入库丢失赔偿";
                case "FeeCorrection":
                    return "FBA物流费调整";
                case "CustomerServiceIssue":
                    return "客户服务问题";
                case "CustomerReturn":
                    Integer sumQuantity = fInventoryDailyMapper.selectSumQuantityBySellerIdAndRelatedIdAndSkuAndWarehouse(sellerId, orderId, sku, "140601", approvalDate);
                    if (null == sumQuantity) {
                        sumQuantity = 0;
                    }
                    if (sumQuantity != 0) {
                        if (sumQuantity >= (quantity + quantityReimbursedInventory)) {
                            return "退货损坏赔偿";
                        }
                    }
                    Integer sumQuantity2 = fInventoryDailyMapper.selectSumQuantityBySellerIdAndRelatedIdAndSkuAndWarehouse(sellerId, orderId, sku, "140201", approvalDate);
                    if (null != sumQuantity2) {
                        if (sumQuantity2 > 0) {
                            return "未退货赔偿";
                        }
                        if (sumQuantity2 < 0) {
                            return "额外赔偿";
                        }
                    }
                    break;
            }
        }
        return "其他";
    }

    /**
     * 获取costUnit
     *
     * @param sellerId
     * @param country
     * @param sku
     * @param amazonOrderId
     * @return
     */
    public Map<String, Double> getCostUnit(String sellerId, String country, String sku, String amazonOrderId) {
        if (!StringUtils.isEmpty(sellerId) && !StringUtils.isEmpty(country) && !StringUtils.isEmpty(sku) && !StringUtils.isEmpty(amazonOrderId)) {
            Double amount = fFbaShipmentSalesMapper.selectSumAmountBySellerIdAndCountryAndSkuAndAmazonOrderId(sellerId, country, sku, amazonOrderId);
            Integer quantity = fFbaShipmentSalesMapper.selectSumQuantityBySellerIdAndCountryAndSkuAndAmazonOrderId(sellerId, country, sku, amazonOrderId);
            if (null != amount && null != quantity && amount != 0.0 && quantity != 0) {
                return new HashMap<String, Double>(1) {{
                    put("costUnit1", new BigDecimal(amount / quantity).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                }};
            }
            Map<String, Object> amountAndQuantityMap = fInventoryDailyMapper.selectSumAmountAndSumQuantityBySellerIdAndCountryAndSkuAndWarehouse(sellerId, country, sku, null);
            if (null != amountAndQuantityMap && !amountAndQuantityMap.isEmpty()) {
                if (null != amountAndQuantityMap.get("amount") && null != amountAndQuantityMap.get("quantity")) {
                    Double amount2 = new Double(amountAndQuantityMap.get("amount").toString());
                    Integer quantity2 = new Integer(amountAndQuantityMap.get("quantity").toString());
                    if (amount2 != 0 && quantity2 != 0) {
                        return new HashMap<String, Double>(1) {{
                            put("costUnit2", new BigDecimal(amount2 / quantity2).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                        }};
                    }
                }
            }
        }
        return null;
    }


    /**
     * 根据type获取借方科目 赔偿数据
     *
     * @param type
     * @return
     */
    public String getDebitSubjectIdFromReimbursement(String type) {
        if (StringUtils.isEmpty(type)) {
            return "";
        }
        return cwfzFinancialSubjectsMapper.selectDebitSubjectIdByTypeAndForm(type, "赔偿");
    }

    /**
     * 根据type获取借方科目 赔偿下推数据
     *
     * @param type
     * @return
     */
    public String getDebitSubjectIdFromReimbursementPush(String type) {
        if (StringUtils.isEmpty(type)) {
            return "";
        }
        return cwfzFinancialSubjectsMapper.selectDebitSubjectIdByTypeAndForm(type, "赔偿下推");
    }


    /**
     * 根据type获取贷方科目 赔偿数据
     *
     * @param type
     * @return
     */
    public String getCreditSubjectIdFromReimbursement(String type) {
        if (StringUtils.isEmpty(type)) {
            return "";
        }
        return cwfzFinancialSubjectsMapper.selectCreditSubjectIdByTypeAndForm(type, "赔偿");
    }

    /**
     * 根据type获取贷方科目 赔偿数据下推数据
     *
     * @param type
     * @return
     */
    public String getCreditSubjectIdFromReimbursementPush(String type) {
        if (StringUtils.isEmpty(type)) {
            return "";
        }
        return cwfzFinancialSubjectsMapper.selectCreditSubjectIdByTypeAndForm(type, "赔偿下推");
    }


}
